package com.example.store.service.impl;

import com.example.store.entity.Address;
import com.example.store.mapper.AddressMapper;
import com.example.store.service.IAddressService;
import com.example.store.service.IDistrictService;
import com.example.store.service.ex.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

@Service
public class AddressServiceImpl implements IAddressService {

    @Autowired
    private AddressMapper addressMapper;

    @Autowired
    private IDistrictService districtService;

    @Value("${user.address.max-count}")
    private int maxCount;
    /**
     * 分析业务逻辑
     * 根据uid调用countByUid方法，查询地址数量是否超标
     * @param uid 当前用户的uid
     * @param username  当前用户的姓名
     * @param address 用户添加的地址数据
     */
    @Override
    public void addNewAddress(Integer uid, String username, Address address) {
    Integer count = addressMapper.countByUid(uid);
    if (count>maxCount){
        throw new AddressCountLimitException("地址数量超出限制");
    }
    address.setUid(uid);
        Integer isDefault = count == 0 ? 1 : 0;
        address.setIsDefault(isDefault);
        // 补全数据：4项日志
        Date now = new Date();
        String provinceName = districtService.findNameByCode(address.getProvinceCode());
        String cityName = districtService.findNameByCode(address.getCityCode());
        String areaName = districtService.findNameByCode(address.getAreaCode());
        address.setCityName(cityName);
        address.setProvinceName(provinceName);
        address.setAreaName(areaName);
        address.setCreatedUser(username);
        address.setCreatedTime(now);
        address.setModifiedUser(username);
        address.setModifiedTime(now);

        // 调用addressMapper的insert(Address address)方法插入收货地址数据，并获取返回的受影响行数
        Integer rows = addressMapper.insert(address);
        // 判断受影响行数是否不为1
        if (rows != 1) {
            // 是：抛出InsertException
            throw new InsertException("插入收货地址数据时出现未知错误，请联系系统管理员！");
        }
    }

    /**
     *
     *
     * @param uid
     * @return
     */
    @Override
    public List<Address> findAddressByUid(Integer uid) {
        List<Address> addresslist = addressMapper.findAddressByUidAddress(uid);
        if (addresslist.size() <= 0) {
            throw new AddressCountLimitException("没找到任何数据");
        }
        for(Address address : addresslist){
            address.setUid(null);
            address.setProvinceCode(null);
            address.setCityCode(null);
            address.setAreaCode(null);
            address.setCreatedUser(null);
            address.setCreatedTime(null);
            address.setModifiedUser(null);
            address.setModifiedTime(null);
        }
        return addresslist;
    }
   //Transction 用来开启事务，为了保证数据一致性
    @Transactional
    @Override
    public void setDefault(Integer aid, Integer uid, String username) {
        //根据aid，调用方法，查看是否真的存在这条数据

        Address result = addressMapper.findByAid(aid);
        if (result == null) {
            throw new AddressNotFoundException("没有找到对应地址");
        }
        /**
         * 1.将所有地址数据设置为非默认
         * 2.将指定地址数据设置为默认
         */
        Integer allnot = addressMapper.updateNonDefaultByUid(uid);
        if (allnot<1){
            throw new UpdateException("设置非默认时出现未知错误，请联系系统管理员");
        }
        Integer rows = addressMapper.updateDefaultByAid(aid, username, new Date());
        if (rows!=1){
            throw new UpdateException("设置默认数据时出现未知错误，请联系系统管理员");
        }

    }

    @Override
    public Address getByAid(Integer aid, Integer uid) {
        // 根据收货地址数据id，查询收货地址详情
        Address address = addressMapper.findByAid(aid);

        if (address == null) {
            throw new AddressNotFoundException("尝试访问的收货地址数据不存在");
        }
        if (!address.getUid().equals(uid)) {
            throw new AccessDeniedException("非法访问");
        }
        address.setProvinceCode(null);
        address.setCityCode(null);
        address.setAreaCode(null);
        address.setCreatedUser(null);
        address.setCreatedTime(null);
        address.setModifiedUser(null);
        address.setModifiedTime(null);
        return address;

    }
}
